<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>RocketMQ事务消息深度解析</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8fafc;
            color: #1e293b;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #2563eb 0%, #1e40af 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .code-block {
            font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
            background-color: #1e293b;
            color: #e2e8f0;
            border-radius: 0.5rem;
        }
        .feature-icon {
            width: 48px;
            height: 48px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 12px;
            color: white;
            margin-bottom: 1rem;
        }
        .highlight-box {
            position: relative;
            border-left: 4px solid #2563eb;
            background-color: #eff6ff;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4">
        <div class="max-w-5xl mx-auto">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-2/3">
                    <h1 class="text-4xl md:text-5xl font-bold mb-6">RocketMQ事务消息</h1>
                    <p class="text-xl md:text-2xl text-blue-100 mb-8 leading-relaxed">
                        分布式系统中的数据一致性保障机制，实现消息发送与本地事务的原子性操作
                    </p>
                    <div class="flex flex-wrap gap-4">
                        <div class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center">
                            <i class="fas fa-atom mr-2"></i>
                            <span>分布式事务</span>
                        </div>
                        <div class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center">
                            <i class="fas fa-exchange-alt mr-2"></i>
                            <span>两阶段提交</span>
                        </div>
                        <div class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center">
                            <i class="fas fa-shield-alt mr-2"></i>
                            <span>数据一致性</span>
                        </div>
                    </div>
                </div>
                <div class="md:w-1/3 mt-10 md:mt-0">
                    <div class="bg-white bg-opacity-10 p-6 rounded-xl backdrop-blur-sm">
                        <h3 class="text-xl font-semibold mb-4">核心特点</h3>
                        <ul class="space-y-3">
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-blue-300 mr-2 mt-1"></i>
                                <span>支持分布式事务的最终一致性</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-blue-300 mr-2 mt-1"></i>
                                <span>确保消息发送与本地事务原子性</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-blue-300 mr-2 mt-1"></i>
                                <span>提供事务回查机制</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-blue-300 mr-2 mt-1"></i>
                                <span>降低系统复杂度</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="max-w-5xl mx-auto px-4 py-16">
        <!-- Concept Section -->
        <section class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-lightbulb text-blue-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">事务消息的概念</h2>
            </div>
            <div class="prose max-w-none text-gray-700 text-lg leading-relaxed">
                <p class="mb-6">
                    RocketMQ事务消息是指消息发送和本地事务执行捆绑在一起，保证本地事务和消息发送要么都成功，要么都失败的一种机制。事务消息是RocketMQ实现分布式事务的核心功能，主要用于解决分布式系统中的数据一致性问题。
                </p>
                
                <div class="grid md:grid-cols-2 gap-6 mt-10">
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <div class="feature-icon bg-blue-600">
                            <i class="fas fa-link text-xl"></i>
                        </div>
                        <h3 class="text-xl font-semibold mb-3">原子性保障</h3>
                        <p>确保消息发送与本地事务执行作为一个原子单元，要么全部成功，要么全部失败回滚。</p>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <div class="feature-icon bg-purple-600">
                            <i class="fas fa-redo-alt text-xl"></i>
                        </div>
                        <h3 class="text-xl font-semibold mb-3">回查机制</h3>
                        <p>当事务状态不确定时，Broker会定期回查Producer，确保事务最终状态得到确认。</p>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <div class="feature-icon bg-green-600">
                            <i class="fas fa-project-diagram text-xl"></i>
                        </div>
                        <h3 class="text-xl font-semibold mb-3">分布式协调</h3>
                        <p>无需依赖外部事务协调器，降低系统复杂度，提高性能。</p>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <div class="feature-icon bg-red-600">
                            <i class="fas fa-shield-alt text-xl"></i>
                        </div>
                        <h3 class="text-xl font-semibold mb-3">最终一致性</h3>
                        <p>通过两阶段提交变种实现分布式系统的数据最终一致性。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Implementation Section -->
        <section class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-cogs text-blue-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">事务消息的实现原理</h2>
            </div>
            
            <div class="mb-10">
                <h3 class="text-2xl font-semibold mb-6 text-blue-800">1. 事务消息发送流程</h3>
                <div class="mb-8">
                    <div class="mermaid">
                        graph TD
                            A[Producer] -->|1. 发送半消息| B[Broker]
                            B -->|2. 返回确认| A
                            A -->|3. 执行本地事务| C[本地事务]
                            C -->|4a. 提交| A
                            C -->|4b. 回滚| A
                            C -->|4c. 未知| A
                            A -->|5. 发送事务状态| B
                            B -->|6. 检查状态| A
                    </div>
                </div>
                <div class="space-y-6">
                    <div class="highlight-box p-6 rounded-lg">
                        <h4 class="text-xl font-semibold mb-3 flex items-center">
                            <span class="w-8 h-8 bg-blue-600 text-white rounded-full flex items-center justify-center mr-3">1</span>
                            发送半消息（Half Message）
                        </h4>
                        <ul class="list-disc pl-6 space-y-2">
                            <li>Producer发送事务消息的第一步是发送半消息到Broker</li>
                            <li>半消息对Consumer不可见，存储在特定的主题中</li>
                            <li>Broker返回半消息发送结果给Producer</li>
                        </ul>
                    </div>
                    <div class="highlight-box p-6 rounded-lg">
                        <h4 class="text-xl font-semibold mb-3 flex items-center">
                            <span class="w-8 h-8 bg-blue-600 text-white rounded-full flex items-center justify-center mr-3">2</span>
                            执行本地事务
                        </h4>
                        <ul class="list-disc pl-6 space-y-2">
                            <li>Producer收到半消息发送成功的响应后，执行本地事务</li>
                            <li>本地事务执行有三种可能结果：提交、回滚或未知</li>
                        </ul>
                    </div>
                    <div class="highlight-box p-6 rounded-lg">
                        <h4 class="text-xl font-semibold mb-3 flex items-center">
                            <span class="w-8 h-8 bg-blue-600 text-white rounded-full flex items-center justify-center mr-3">3</span>
                            提交或回滚事务
                        </h4>
                        <ul class="list-disc pl-6 space-y-2">
                            <li>如果本地事务执行成功，Producer向Broker发送提交消息的请求</li>
                            <li>如果本地事务执行失败，Producer向Broker发送回滚消息的请求</li>
                            <li>如果因网络问题等原因导致未收到本地事务执行结果，Broker会触发事务状态回查机制</li>
                        </ul>
                    </div>
                </div>
            </div>

            <div class="mb-10">
                <h3 class="text-2xl font-semibold mb-6 text-blue-800">2. 事务状态回查机制</h3>
                <div class="grid md:grid-cols-2 gap-6 mb-8">
                    <div>
                        <div class="bg-white p-6 rounded-xl shadow-md h-full">
                            <h4 class="text-lg font-semibold mb-4 flex items-center">
                                <i class="fas fa-clock text-yellow-500 mr-2"></i>
                                回查机制流程
                            </h4>
                            <ol class="list-decimal pl-5 space-y-2">
                                <li>Broker维护定时任务扫描超时半消息</li>
                                <li>向Producer发起回查请求</li>
                                <li>Producer检查本地事务状态</li>
                                <li>返回事务状态（提交/回滚）</li>
                                <li>Broker根据结果处理半消息</li>
                            </ol>
                        </div>
                    </div>
                    <div>
                        <div class="bg-white p-6 rounded-xl shadow-md h-full">
                            <h4 class="text-lg font-semibold mb-4 flex items-center">
                                <i class="fas fa-cog text-green-500 mr-2"></i>
                                关键配置参数
                            </h4>
                            <div class="space-y-3">
                                <div>
                                    <div class="font-medium">默认回查间隔时间</div>
                                    <div class="text-gray-500">60秒</div>
                                </div>
                                <div>
                                    <div class="font-medium">默认回查次数</div>
                                    <div class="text-gray-500">15次</div>
                                </div>
                                <div>
                                    <div class="font-medium">最大回查次数</div>
                                    <div class="text-gray-500">可配置，超过后默认回滚</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div>
                <h3 class="text-2xl font-semibold mb-6 text-blue-800">3. 事务消息的存储结构</h3>
                <div class="grid md:grid-cols-3 gap-6">
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <div class="font-semibold text-lg mb-3 flex items-center">
                            <i class="fas fa-database text-purple-500 mr-2"></i>
                            半消息存储
                        </div>
                        <p>存储在特殊的系统主题中：RMQ_SYS_TRANS_HALF_TOPIC</p>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <div class="font-semibold text-lg mb-3 flex items-center">
                            <i class="fas fa-exchange-alt text-blue-500 mr-2"></i>
                            消息转移
                        </div>
                        <p>提交的事务消息会被转移到目标主题中</p>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <div class="font-semibold text-lg mb-3 flex items-center">
                            <i class="fas fa-trash-alt text-red-500 mr-2"></i>
                            回滚处理
                        </div>
                        <p>回滚的事务消息会被标记并定期清理</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Consistency Section -->
        <section class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-lock text-blue-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">RocketMQ如何保证分布式事务一致性</h2>
            </div>

            <div class="grid md:grid-cols-3 gap-6">
                <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                    <h3 class="text-xl font-semibold mb-4 flex items-center">
                        <i class="fas fa-pause-circle text-blue-500 mr-3"></i>
                        半消息机制
                    </h3>
                    <ul class="space-y-2 text-gray-700">
                        <li class="flex items-start">
                            <i class="fas fa-check text-blue-400 mr-2 mt-1"></i>
                            <span>对Consumer不可见，避免消费未确认消息</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-blue-400 mr-2 mt-1"></i>
                            <span>在事务提交前，消息不会被投递</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-blue-400 mr-2 mt-1"></i>
                            <span>解耦消息发送和事务执行</span>
                        </li>
                    </ul>
                </div>
                <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                    <h3 class="text-xl font-semibold mb-4 flex items-center">
                        <i class="fas fa-search text-green-500 mr-3"></i>
                        事务回查机制
                    </h3>
                    <ul class="space-y-2 text-gray-700">
                        <li class="flex items-start">
                            <i class="fas fa-check text-green-400 mr-2 mt-1"></i>
                            <span>解决异常情况下的事务状态确认</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-green-400 mr-2 mt-1"></i>
                            <span>持久化事务状态，支持系统重启恢复</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-green-400 mr-2 mt-1"></i>
                            <span>提供事务超时处理机制</span>
                        </li>
                    </ul>
                </div>
                <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                    <h3 class="text-xl font-semibold mb-4 flex items-center">
                        <i class="fas fa-sync-alt text-purple-500 mr-3"></i>
                        幂等性设计
                    </h3>
                    <ul class="space-y-2 text-gray-700">
                        <li class="flex items-start">
                            <i class="fas fa-check text-purple-400 mr-2 mt-1"></i>
                            <span>Producer实现幂等的回查接口</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-purple-400 mr-2 mt-1"></i>
                            <span>事务提交和回滚操作设计为幂等</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-purple-400 mr-2 mt-1"></i>
                            <span>重复执行不会导致错误</span>
                        </li>
                    </ul>
                </div>
            </div>
        </section>

        <!-- Use Cases Section -->
        <section class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-shopping-cart text-blue-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">事务消息的应用场景</h2>
            </div>

            <div class="grid md:grid-cols-3 gap-6">
                <div class="bg-white rounded-xl overflow-hidden shadow-md card-hover">
                    <div class="bg-blue-600 p-4 text-white">
                        <h3 class="text-xl font-semibold flex items-center">
                            <i class="fas fa-store mr-3"></i>
                            电商订单处理
                        </h3>
                    </div>
                    <div class="p-6">
                        <div class="mb-4 font-medium">涉及步骤：</div>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>创建订单记录</li>
                            <li>扣减库存</li>
                            <li>生成支付单</li>
                        </ul>
                        <div class="mt-4 p-4 bg-blue-50 rounded-lg">
                            <div class="font-medium mb-2">事务消息应用：</div>
                            <ol class="list-decimal pl-5 space-y-1 text-sm">
                                <li>发送半消息（订单创建消息）</li>
                                <li>执行本地事务（创建订单记录）</li>
                                <li>提交事务消息，触发后续操作</li>
                            </ol>
                        </div>
                    </div>
                </div>
                <div class="bg-white rounded-xl overflow-hidden shadow-md card-hover">
                    <div class="bg-green-600 p-4 text-white">
                        <h3 class="text-xl font-semibold flex items-center">
                            <i class="fas fa-money-bill-wave mr-3"></i>
                            金融支付系统
                        </h3>
                    </div>
                    <div class="p-6">
                        <div class="mb-4 font-medium">涉及操作：</div>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>扣减付款方账户余额</li>
                            <li>增加收款方账户余额</li>
                        </ul>
                        <div class="mt-4 p-4 bg-green-50 rounded-lg">
                            <div class="font-medium mb-2">事务消息应用：</div>
                            <ol class="list-decimal pl-5 space-y-1 text-sm">
                                <li>发送半消息（转账消息）</li>
                                <li>执行本地事务（扣减付款方余额）</li>
                                <li>提交事务消息，触发收款操作</li>
                            </ol>
                        </div>
                    </div>
                </div>
                <div class="bg-white rounded-xl overflow-hidden shadow-md card-hover">
                    <div class="bg-purple-600 p-4 text-white">
                        <h3 class="text-xl font-semibold flex items-center">
                            <i class="fas fa-award mr-3"></i>
                            积分系统
                        </h3>
                    </div>
                    <div class="p-6">
                        <div class="mb-4 font-medium">涉及操作：</div>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>记录用户行为</li>
                            <li>更新用户积分</li>
                        </ul>
                        <div class="mt-4 p-4 bg-purple-50 rounded-lg">
                            <div class="font-medium mb-2">事务消息应用：</div>
                            <ol class="list-decimal pl-5 space-y-1 text-sm">
                                <li>发送半消息（积分变更消息）</li>
                                <li>执行本地事务（记录用户行为）</li>
                                <li>提交事务消息，触发积分更新</li>
                            </ol>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Best Practices Section -->
        <section>
            <div class="flex items-center mb-8">
                <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-star text-blue-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">事务消息的最佳实践</h2>
            </div>

            <div class="grid md:grid-cols-2 gap-8">
                <div>
                    <h3 class="text-2xl font-semibold mb-6 text-blue-800">1. 实现可靠的事务状态回查</h3>
                    <div class="code-block p-6 rounded-lg mb-6 overflow-x-auto">
                        <pre><code class="text-sm">public class TransactionListenerImpl implements TransactionListener {
    private ConcurrentHashMap&lt;String, Integer&gt; localTrans = new ConcurrentHashMap&lt;&gt;();
    
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        // 执行本地事务
        String transactionId = msg.getTransactionId();
        try {
            // 业务逻辑处理
            boolean success = executeBusinessLogic(msg);
            if (success) {
                localTrans.put(transactionId, 1); // 1表示成功
                return LocalTransactionState.COMMIT_MESSAGE;
            } else {
                localTrans.put(transactionId, 0); // 0表示失败
                return LocalTransactionState.ROLLBACK_MESSAGE;
            }
        } catch (Exception e) {
            localTrans.put(transactionId, 2); // 2表示未知
            return LocalTransactionState.UNKNOW;
        }
    }
    
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        // 事务状态回查
        String transactionId = msg.getTransactionId();
        Integer status = localTrans.get(transactionId);
        if (status != null) {
            switch (status) {
                case 1:
                    return LocalTransactionState.COMMIT_MESSAGE;
                case 0:
                    return LocalTransactionState.ROLLBACK_MESSAGE;
                default:
                    return LocalTransactionState.UNKNOW;
            }
        }
        return LocalTransactionState.UNKNOW;
    }
}</code></pre>
                    </div>
                </div>
                <div>
                    <h3 class="text-2xl font-semibold mb-6 text-blue-800">2. 事务消息发送示例</h3>
                    <div class="code-block p-6 rounded-lg mb-6 overflow-x-auto">
                        <pre><code class="text-sm">public void sendTransactionMessage() {
    // 创建事务消息生产者
    TransactionMQProducer producer = new TransactionMQProducer("transaction_producer_group");
    
    // 设置NameServer地址
    producer.setNamesrvAddr("localhost:9876");
    
    // 设置事务监听器
    TransactionListener transactionListener = new TransactionListenerImpl();
    producer.setTransactionListener(transactionListener);
    
    // 启动生产者
    producer.start();
    
    try {
        // 构建消息
        Message msg = new Message("TopicTest", "TagA", "KEY", 
            ("Hello RocketMQ Transaction Message").getBytes());
        
        // 发送事务消息
        SendResult sendResult = producer.sendMessageInTransaction(msg, null);
        System.out.println("发送结果：" + sendResult);
    } catch (Exception e) {
        e.printStackTrace();
    }
}</code></pre>
                    </div>
                </div>
            </div>

            <div class="mt-10">
                <h3 class="text-2xl font-semibold mb-6 text-blue-800">3. 注意事项</h3>
                <div class="grid md:grid-cols-2 gap-6">
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <h4 class="text-lg font-semibold mb-3 flex items-center">
                            <i class="fas fa-sync-alt text-red-500 mr-2"></i>
                            事务回查接口的幂等性
                        </h4>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>回查接口必须实现幂等，因为可能被多次调用</li>
                            <li>建议使用数据库事务表记录事务状态</li>
                        </ul>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <h4 class="text-lg font-semibold mb-3 flex items-center">
                            <i class="fas fa-clock text-blue-500 mr-2"></i>
                            事务超时设置
                        </h4>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>合理设置事务超时时间和回查次数</li>
                            <li>避免事务长时间处于中间状态</li>
                        </ul>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <h4 class="text-lg font-semibold mb-3 flex items-center">
                            <i class="fas fa-exclamation-triangle text-yellow-500 mr-2"></i>
                            异常处理
                        </h4>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>完善的异常处理机制，确保各种异常情况下事务状态的正确性</li>
                            <li>考虑系统重启、网络中断等场景</li>
                        </ul>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <h4 class="text-lg font-semibold mb-3 flex items-center">
                            <i class="fas fa-hourglass-half text-green-500 mr-2"></i>
                            避免长事务
                        </h4>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>事务执行时间不宜过长，影响系统吞吐量</li>
                            <li>复杂业务可拆分为多个小事务</li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12 px-4">
        <div class="max-w-5xl mx-auto">
            <div class="text-center">
                <h3 class="text-xl font-semibold text-white mb-2">技术小馆</h3>
                <a href="http://www.yuque.com/jtostring" class="text-blue-400 hover:text-blue-300 transition-colors duration-200">
                    http://www.yuque.com/jtostring
                </a>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'dark',
            flowchart: {
                useMaxWidth: false,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>